﻿using JX.Core.Entity;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace JX.Core
{
	/// <summary>
	/// 仓储接口(基于Dapper)
	/// </summary>
	/// <typeparam name="T"></typeparam>
	public interface IRepositoryDapper<T> where T : class
	{
		#region 得到第一行第一列的值
		/// <summary>
		/// 直接获取特定一个或者多个字段的值,多个字段需要声明Model。
		/// 例：var s = testDal.GetScalar《string》(m=>m.Name,m=>m.Code==1,m => m.OrderBy(item => item.ID).ThenBy(item => item.Name));
		/// var s = testDal.GetScalar《StoreM》(m=>new StoreM { Name1= m.Name, Code=m.Code },m=>m.Code==2,m => m.OrderBy(item => item.ID).ThenBy(item => item.Name));
		/// var s = testDal.GetScalar《dynamic》(m=>new { m.Name,m.Code },m=>m.Code==3,m => m.OrderBy(item => item.ID).ThenBy(item => item.Name));
		/// </summary>
		/// <typeparam name="TResult">数据结果</typeparam>
		/// <param name="scalar">要返回的结果，Lamda表达式（p=>p.Id）</param>
		/// <param name="predicate">查询条件，Lamda表达式（p=>p.Id==Id）</param>
		/// <param name="orderby">排序字段，Lamda表达式（p.OrderByDescending(item=>item.Timestamp).ThenBy(item=>item.Title)）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		TResult GetScalar<TResult>(Expression<Func<T, TResult>> scalar,
			Expression<Func<T, bool>> predicate = null,
			Expression<Func<IQueryable<T>, IOrderedQueryable<T>>> orderby = null,
			WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);
		/// <summary>
		/// 直接获取特定一个或者多个字段的值,多个字段需要声明Model。
		/// 例：var s = testDal.GetScalar《string》(m=>m.Name,m=>m.Code==1,m => m.OrderBy(item => item.ID).ThenBy(item => item.Name));
		/// var s = testDal.GetScalar《StoreM》(m=>new StoreM { Name1= m.Name, Code=m.Code },m=>m.Code==2,m => m.OrderBy(item => item.ID).ThenBy(item => item.Name));
		/// var s = testDal.GetScalar《dynamic》(m=>new { m.Name,m.Code },m=>m.Code==3,m => m.OrderBy(item => item.ID).ThenBy(item => item.Name));
		/// </summary>
		/// <typeparam name="TResult">数据结果</typeparam>
		/// <param name="scalar">要返回的结果，Lamda表达式（p=>p.Id）</param>
		/// <param name="predicate">查询条件，Lamda表达式（p=>p.Id==Id）</param>
		/// <param name="orderby">排序字段，Lamda表达式（p.OrderByDescending(item=>item.Timestamp).ThenBy(item=>item.Title)）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		Task<TResult> GetScalarAsync<TResult>(Expression<Func<T, TResult>> scalar,
			Expression<Func<T, bool>> predicate = null,
			Expression<Func<IQueryable<T>, IOrderedQueryable<T>>> orderby = null,
			WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);

		/// <summary>
		/// 得到第一行第一列的值
		/// </summary>
		/// <typeparam name="TResult">数据结果</typeparam>
		/// <param name="statistic">要返回的字段（如：count(*) 或者 UserName）</param>
		/// <param name="strWhere">参数化查询条件(例如: and Name = @Name )</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		TResult GetScalar<TResult>(string statistic, string strWhere = "", object param = null, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);
		/// <summary>
		/// 得到第一行第一列的值（异步方式）
		/// </summary>
		/// <typeparam name="TResult">数据结果</typeparam>
		/// <param name="statistic">要返回的字段（如：count(*) 或者 UserName）</param>
		/// <param name="strWhere">参数化查询条件(例如: and Name = @Name )</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		Task<TResult> GetScalarAsync<TResult>(string statistic, string strWhere = "", object param = null, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);
		#endregion

		#region 得到所有行数
		/// <summary>
		/// 得到所有行数
		/// </summary>
		/// <param name="predicate">查询条件，Lamda表达式（p=>p.Id==Id）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		int GetCount(Expression<Func<T, bool>> predicate,WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);
		/// <summary>
		/// 得到所有行数
		/// </summary>
		/// <param name="predicate">查询条件，Lamda表达式（p=>p.Id==Id）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		Task<int> GetCountAsync(Expression<Func<T, bool>> predicate, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);
		/// <summary>
		/// 得到所有行数
		/// </summary>
		/// <param name="strWhere">参数化查询条件(例如: and Name = @Name )</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		int GetCount(string strWhere = "", object param = null, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);
		/// <summary>
		/// 得到所有行数（异步方式）
		/// </summary>
		/// <param name="strWhere">参数化查询条件(例如: and Name = @Name )</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		Task<int> GetCountAsync(string strWhere = "", object param = null, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);
		#endregion

		#region 得到最大ID、最新ID
		/// <summary>
		/// 得到数据表中第一个主键的最大数值
		/// </summary>
		/// <returns></returns>
		int GetMaxID();
		/// <summary>
		/// 得到数据表中第一个主键的最大数值（异步方式）
		/// </summary>
		/// <returns></returns>
		Task<int> GetMaxIDAsync();

		/// <summary>
		/// 得到数据表中第一个主键的最大数值加1
		/// </summary>
		/// <returns></returns>
		int GetNewID();
		/// <summary>
		/// 得到数据表中第一个主键的最大数值加1（异步方式）
		/// </summary>
		/// <returns></returns>
		Task<int> GetNewIDAsync();
		#endregion

		#region 验证是否存在
		/// <summary>
		/// 验证当前条件是否存在相同项
		/// </summary>
		/// <param name="predicate"></param>
		/// <returns></returns>
		bool IsExist(Expression<Func<T, bool>> predicate);
		/// <summary>
		/// 验证当前条件是否存在相同项（异步方式）
		/// </summary>
		/// <param name="predicate"></param>
		/// <returns></returns>
		Task<bool> IsExistAsync(Expression<Func<T, bool>> predicate);
		/// <summary>
		/// 检查数据是否存在
		/// </summary>
		/// <param name="strWhere">参数化查询条件(例如: and Name = @Name )</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <returns></returns>
		bool IsExist(string strWhere = "", object param = null);

		/// <summary>
		/// 检查数据是否存在（异步方式）
		/// </summary>
		/// <param name="strWhere">参数化查询条件(例如: and Name = @Name )</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <returns></returns>
		Task<bool> IsExistAsync(string strWhere = "", object param = null);
		#endregion

		#region 添加
		/// <summary>
		/// 增加一条记录
		/// </summary>
		/// <param name="entity">实体模型</param>
		/// <returns></returns>
		bool Add(T entity);
		/// <summary>
		/// 增加一条记录（异步方式）
		/// </summary>
		/// <param name="entity">实体模型</param>
		/// <returns></returns>
		Task<bool> AddAsync(T entity);

		/// <summary>
		/// 增加多条记录，同一模型
		/// </summary>
		/// <param name="entityList">实体模型集合</param>
		/// <returns></returns>
		bool AddList(IList<T> entityList);
		/// <summary>
		/// 增加多条记录，同一模型（异步方式）
		/// </summary>
		/// <param name="entityList">实体模型集合</param>
		/// <returns></returns>
		Task<bool> AddListAsync(IList<T> entityList);

		/// <summary>
		/// 增加一条记录，返回新的ID号。需要有一个单一主键，并且开启有标识符属性
		/// </summary>
		/// <param name="entity">实体模型</param>
		/// <returns></returns>
		int Insert(T entity);
		/// <summary>
		/// 增加一条记录，返回新的ID号。需要有一个单一主键，并且开启有标识符属性（异步方式）
		/// </summary>
		/// <param name="entity">实体模型</param>
		/// <returns></returns>
		Task<int> InsertAsync(T entity);

		/// <summary>
		/// 增加或更新一条记录
		/// </summary>
		/// <param name="entity">实体模型</param>
		/// <param name="IsSave">是否增加</param>
		/// <returns></returns>
		bool AddOrUpdate(T entity, bool IsSave);
		/// <summary>
		/// 增加或更新一条记录（异步方式）
		/// </summary>
		/// <param name="entity">实体模型</param>
		/// <param name="IsSave">是否增加</param>
		/// <returns></returns>
		Task<bool> AddOrUpdateAsync(T entity, bool IsSave);
		#endregion

		#region 删除
		/// <summary>
		/// 通过Lamda表达式，删除一条或多条记录
		/// </summary>
		/// <param name="predicate">Lamda表达式（p=>p.Id==Id）</param>
		/// <returns></returns>
		bool Delete(Expression<Func<T, bool>> predicate);
		/// <summary>
		/// 通过Lamda表达式，删除一条或多条记录（异步方式）
		/// </summary>
		/// <param name="predicate">Lamda表达式（p=>p.Id==Id）</param>
		/// <returns></returns>
		Task<bool> DeleteAsync(Expression<Func<T, bool>> predicate);
		/// <summary>
		/// 删除一条或多条记录
		/// </summary>
		/// <param name="strWhere">参数化删除条件(例如: and Name = @Name )</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <returns></returns>
		bool Delete(string strWhere = "", object param = null);
		/// <summary>
		/// 删除一条或多条记录（异步方式）
		/// </summary>
		/// <param name="strWhere">参数化删除条件(例如: and Name = @Name )</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <returns></returns>
		Task<bool> DeleteAsync(string strWhere = "", object param = null);
		#endregion

		#region 修改
		/// <summary>
		/// 更新一条记录
		/// </summary>
		/// <param name="entity">实体模型</param>
		/// <returns></returns>
		bool Update(T entity);
		/// <summary>
		/// 更新一条记录（异步方式）
		/// </summary>
		/// <param name="entity">实体模型</param>
		/// <returns></returns>
		Task<bool> UpdateAsync(T entity);

		/// <summary>
		/// 修改一条或多条记录
		/// </summary>
		/// <param name="strColumns">参数化要修改的列（如：ID = @ID,Name = @Name）</param>
		/// <param name="strWhere">参数化修改条件(例如: and ID = @ID)</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <returns></returns>
		bool Update(string strColumns, string strWhere = "", object param = null);
		/// <summary>
		/// 修改一条或多条记录（异步方式）
		/// </summary>
		/// <param name="strColumns">参数化要修改的列（如：ID = @ID,Name = @Name）</param>
		/// <param name="strWhere">参数化修改条件(例如: and ID = @ID)</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <returns></returns>
		Task<bool> UpdateAsync(string strColumns, string strWhere = "", object param = null);

		/// <summary>
		/// 批量更新
		/// </summary>
		/// <param name="entityList"></param>
		/// <returns></returns>
		bool UpdateList(IList<T> entityList);
		/// <summary>
		/// 批量更新
		/// </summary>
		/// <param name="entityList"></param>
		/// <returns></returns>
		Task<bool> UpdateListAsync(IList<T> entityList);
		#endregion

		#region 得到实体
		/// <summary>
		/// 通过Lamda表达式获取实体
		/// </summary>
		/// <param name="predicate">Lamda表达式（p=>p.Id==Id）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		T Get(Expression<Func<T, bool>> predicate, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);
		/// <summary>
		/// 通过Lamda表达式获取实体（异步方式）
		/// </summary>
		/// <param name="predicate">Lamda表达式（p=>p.Id==Id）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		Task<T> GetAsync(Expression<Func<T, bool>> predicate, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);
		/// <summary>
		/// 获取实体
		/// </summary>
		/// <param name="strWhere">参数化查询条件(例如: and Name = @Name )</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		T Get(string strWhere = "", object param = null, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);
		/// <summary>
		/// 获取实体（异步方式）
		/// </summary>
		/// <param name="strWhere">参数化查询条件(例如: and Name = @Name )</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		Task<T> GetAsync(string strWhere = "", object param = null, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);
		/// <summary>
		/// 获取实体
		/// </summary>
		/// <param name="strJoin">联合查询语句(例：inner join tablename t on t.id=t1.id)</param>
		/// <param name="strWhere">参数化查询条件(例如: and Name = @Name )</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		T Get(string strJoin, string strWhere = "", object param = null, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);
		/// <summary>
		/// 获取实体（异步方式）
		/// </summary>
		/// <param name="strJoin">联合查询语句(例：inner join tablename t on t.id=t1.id)</param>
		/// <param name="strWhere">参数化查询条件(例如: and Name = @Name )</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		Task<T> GetAsync(string strJoin, string strWhere = "", object param = null, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);
		#endregion

		#region 得到实体列表
		/// <summary>
		/// 得到实体列表
		/// </summary>
		/// <param name="predicate">查询条件，Lamda表达式（p=>p.Id==Id）</param>
		/// <param name="orderby">排序字段，Lamda表达式（p.OrderByDescending(item=>item.Timestamp).ThenBy(item=>item.Title)）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		IEnumerable<T> GetList(Expression<Func<T, bool>> predicate,
			Expression<Func<IQueryable<T>, IOrderedQueryable<T>>> orderby = null,
			WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);
		/// <summary>
		/// 得到实体列表
		/// </summary>
		/// <param name="predicate">查询条件，Lamda表达式（p=>p.Id==Id）</param>
		/// <param name="orderby">排序字段，Lamda表达式（p.OrderByDescending(item=>item.Timestamp).ThenBy(item=>item.Title)）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		Task<IEnumerable<T>> GetListAsync(Expression<Func<T, bool>> predicate,
			Expression<Func<IQueryable<T>, IOrderedQueryable<T>>> orderby = null,
			WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);
		/// <summary>
		/// 得到实体列表
		/// </summary>
		/// <param name="strWhere">参数化查询条件(例如: and Name = @Name )</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		IEnumerable<T> GetList(string strWhere = "", object param = null, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);
		/// <summary>
		/// 得到实体列表（异步方式）
		/// </summary>
		/// <param name="strWhere">参数化查询条件(例如: and Name = @Name )</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		Task<IEnumerable<T>> GetListAsync(string strWhere = "", object param = null, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);
		/// <summary>
		/// 得到实体列表
		/// </summary>
		/// <param name="strJoin">联合查询语句(例：inner join tablename t on t.id=t1.id)</param>
		/// <param name="strWhere">参数化查询条件(例如: and Name = @Name )</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		IEnumerable<T> GetList(string strJoin, string strWhere = "", object param = null, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);
		/// <summary>
		/// 得到实体列表（异步方式）
		/// </summary>
		/// <param name="strJoin">联合查询语句(例：inner join tablename t on t.id=t1.id)</param>
		/// <param name="strWhere">参数化查询条件(例如: and Name = @Name )</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		Task<IEnumerable<T>> GetListAsync(string strJoin, string strWhere = "", object param = null, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);
		#endregion

		#region 得到数据列表
		/// <summary>
		/// 返回所有信息
		/// </summary>
		/// <param name="predicate">查询条件，Lamda表达式（p=>p.Id==Id）</param>
		/// <param name="orderby">排序字段，Lamda表达式（p.OrderByDescending(item=>item.Timestamp).ThenBy(item=>item.Title)）</param>
		/// <param name="selector">返回结果（必须是模型中存在的字段）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		IEnumerable<TResult> GetAllData<TResult>(Expression<Func<T, bool>> predicate,
			Expression<Func<IQueryable<T>, IOrderedQueryable<T>>> orderby = null,
			Expression<Func<T, TResult>> selector = null,
			WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);
		/// <summary>
		/// 返回所有信息
		/// </summary>
		/// <param name="predicate">查询条件，Lamda表达式（p=>p.Id==Id）</param>
		/// <param name="orderby">排序字段，Lamda表达式（p.OrderByDescending(item=>item.Timestamp).ThenBy(item=>item.Title)）</param>
		/// <param name="selector">返回结果（必须是模型中存在的字段）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		Task<IEnumerable<TResult>> GetAllDataAsync<TResult>(Expression<Func<T, bool>> predicate,
			Expression<Func<IQueryable<T>, IOrderedQueryable<T>>> orderby = null,
			Expression<Func<T, TResult>> selector = null,
			WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);
		/// <summary>
		/// 返回所有信息
		/// </summary>
		/// <param name="predicate">查询条件，Lamda表达式（p=>p.Id==Id）</param>
		/// <param name="orderby">排序字段，Lamda表达式（p.OrderByDescending(item=>item.Timestamp).ThenBy(item=>item.Title)）</param>
		/// <param name="selector">返回结果（必须是模型中存在的字段）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		IEnumerable<TResult> GetAllData<TEntity, TResult>(Expression<Func<TEntity, bool>> predicate,
			Expression<Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>>> orderby = null,
			Expression<Func<TEntity, TResult>> selector = null,
			WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
			where TEntity : class;
		/// <summary>
		/// 返回所有信息
		/// </summary>
		/// <param name="predicate">查询条件，Lamda表达式（p=>p.Id==Id）</param>
		/// <param name="orderby">排序字段，Lamda表达式（p.OrderByDescending(item=>item.Timestamp).ThenBy(item=>item.Title)）</param>
		/// <param name="selector">返回结果（必须是模型中存在的字段）</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		Task<IEnumerable<TResult>> GetAllDataAsync<TEntity, TResult>(Expression<Func<TEntity, bool>> predicate,
			Expression<Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>>> orderby = null,
			Expression<Func<TEntity, TResult>> selector = null,
			WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
			where TEntity : class;
		/// <summary>
		/// 返回所有信息
		/// </summary>
		/// <typeparam name="TResult"></typeparam>
		/// <param name="tableName">查询表名，可以指定联合查询的SQL语句(例如: Comment LEFT JOIN Users ON Comment.UserName = Users.UserName)</param>
		/// <param name="strWhere">参数化查询条件(例如: and Name = @Name )</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="strExtended">返回的指定列(例如: extended = id + name 或 distinct name)</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		IEnumerable<TResult> GetAllData<TResult>(string tableName, string strWhere = "", object param = null, string strExtended = "*", WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);
		/// <summary>
		/// 返回所有信息
		/// </summary>
		/// <typeparam name="TResult"></typeparam>
		/// <param name="tableName">查询表名，可以指定联合查询的SQL语句(例如: Comment LEFT JOIN Users ON Comment.UserName = Users.UserName)</param>
		/// <param name="strWhere">参数化查询条件(例如: and Name = @Name )</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="strExtended">返回的指定列(例如: extended = id + name 或 distinct name)</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		Task<IEnumerable<TResult>> GetAllDataAsync<TResult>(string tableName, string strWhere = "", object param = null, string strExtended = "*", WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);
		#endregion

		#region 分页
		/// <summary>
		/// 通过存储过程“Common_GetList”，得到分页后的数据
		/// </summary>
		/// <param name="startRowIndexId">开始行索引</param>
		/// <param name="maxNumberRows">每页最大显示数量</param>
		/// <param name="Filter">查询条件(例如: Name = 'name' and id=1 )</param>
		/// <param name="Total">输出参数：查询总数</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		IEnumerable<T> GetListPaged(int startRowIndexId, int maxNumberRows, string Filter, out int Total, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);
		/// <summary>
		/// 通过存储过程“Common_GetList”，得到分页后的数据
		/// </summary>
		/// <param name="startRowIndexId">开始行索引</param>
		/// <param name="maxNumberRows">每页最大显示数量</param>
		/// <param name="StrColumn">返回列名</param>
		/// <param name="TableName">查询表名，可以指定联合查询的SQL语句(例如: Comment LEFT JOIN Users ON Comment.UserName = Users.UserName)</param>
		/// <param name="Filter">查询条件(例如: Name = 'name' and id=1 )</param>
		/// <param name="SortColumn">排序字段名，只能指定一个字段</param>
		/// <param name="Sorts">排序方式（DESC,ASC）</param>
		/// <param name="Total">输出参数：查询总数</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		IEnumerable<T> GetListPaged(int startRowIndexId, int maxNumberRows, string StrColumn, string TableName, string Filter, string SortColumn, string Sorts, out int Total, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);
		/// <summary>
		/// 通过存储过程“Common_GetList”，得到分页后的数据
		/// </summary>
		/// <typeparam name="TResult">实体类</typeparam>
		/// <param name="startRowIndexId">开始行索引</param>
		/// <param name="maxNumberRows">每页最大显示数量</param>
		/// <param name="StrColumn">返回列名</param>
		/// <param name="TableName">查询表名，可以指定联合查询的SQL语句(例如: Comment LEFT JOIN Users ON Comment.UserName = Users.UserName)</param>
		/// <param name="Filter">查询条件(例如: Name = 'name' and id=1 )</param>
		/// <param name="SortColumn">排序字段名，只能指定一个字段</param>
		/// <param name="Sorts">排序方式（DESC,ASC）</param>
		/// <param name="Total">输出参数：查询总数</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		IEnumerable<TResult> GetListPaged<TResult>(int startRowIndexId, int maxNumberRows, string StrColumn, string TableName, string Filter, string SortColumn, string Sorts, out int Total, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);

		/// <summary>
		/// 通过存储过程“Common_GetListBySortColumn”，得到分页后的数据
		/// </summary>
		/// <param name="startRowIndexId">开始行索引</param>
		/// <param name="maxNumberRows">每页最大显示数量</param>
		/// <param name="Filter">查询条件(例如: Name = 'name' and id=1 )</param>
		/// <param name="SortColumnDbType">排序字段的数据类型(如：int)</param>
		/// <param name="SortColumn">排序字段名，只能指定一个字段</param>
		/// <param name="Sorts">排序方式（DESC,ASC）</param>
		/// <param name="Total">输出参数：查询总数</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		IEnumerable<T> GetListPagedBySortColumn(int startRowIndexId, int maxNumberRows, string Filter, string SortColumnDbType, string SortColumn, string Sorts, out int Total, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);
		/// <summary>
		/// 通过存储过程“Common_GetListBySortColumn”，得到分页后的数据
		/// </summary>
		/// <param name="startRowIndexId">开始行索引</param>
		/// <param name="maxNumberRows">每页最大显示数量</param>
		/// <param name="PrimaryColumn">主键字段名</param>
		/// <param name="StrColumn">返回列名</param>
		/// <param name="TableName">查询表名，可以指定联合查询的SQL语句(例如: Comment LEFT JOIN Users ON Comment.UserName = Users.UserName)</param>
		/// <param name="Filter">查询条件(例如: Name = 'name' and id=1 )</param>
		/// <param name="SortColumnDbType">排序字段的数据类型(默认：int)</param>
		/// <param name="SortColumn">排序字段名，只能指定一个字段</param>
		/// <param name="Sorts">排序方式（DESC,ASC）</param>
		/// <param name="Total">输出参数：查询总数</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		IEnumerable<T> GetListPagedBySortColumn(int startRowIndexId, int maxNumberRows, string PrimaryColumn, string StrColumn, string TableName, string Filter, string SortColumnDbType, string SortColumn, string Sorts, out int Total, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);
		/// <summary>
		/// 通过存储过程“Common_GetListBySortColumn”，得到分页后的数据
		/// </summary>
		/// <typeparam name="TResult">实体类</typeparam>
		/// <param name="startRowIndexId">开始行索引</param>
		/// <param name="maxNumberRows">每页最大显示数量</param>
		/// <param name="PrimaryColumn">主键字段名</param>
		/// <param name="StrColumn">返回列名</param>
		/// <param name="TableName">查询表名，可以指定联合查询的SQL语句(例如: Comment LEFT JOIN Users ON Comment.UserName = Users.UserName)</param>
		/// <param name="Filter">查询条件(例如: Name = 'name' and id=1 )</param>
		/// <param name="SortColumnDbType">排序字段的数据类型(如：int)</param>
		/// <param name="SortColumn">排序字段名，只能指定一个字段</param>
		/// <param name="Sorts">排序方式（DESC,ASC）</param>
		/// <param name="Total">输出参数：查询总数</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		IEnumerable<TResult> GetListPagedBySortColumn<TResult>(int startRowIndexId, int maxNumberRows, string PrimaryColumn, string StrColumn, string TableName, string Filter, string SortColumnDbType, string SortColumn, string Sorts, out int Total, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);

		/// <summary>
		/// 通过存储过程“Statistics_GetListByPage”，得到分页后的数据
		/// </summary>
		/// <param name="startRowIndexId">开始行索引</param>
		/// <param name="maxNumberRows">每页最大显示数量</param>
		/// <param name="Filter">查询条件(例如: Name = 'name' and id=1 )</param>
		/// <param name="ID">用于分页的、不重复的字段</param>
		/// <param name="Group">分组语句（例：group by name,sex）</param>
		/// <param name="Total">输出参数：查询总数</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		IEnumerable<T> GetListPagedByStat(int startRowIndexId, int maxNumberRows, string Filter, string ID, string Group, out int Total, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);
		/// <summary>
		/// 通过存储过程“Statistics_GetListByPage”，得到分页后的数据
		/// </summary>
		/// <param name="startRowIndexId">开始行索引</param>
		/// <param name="maxNumberRows">每页最大显示数量</param>
		/// <param name="StrColumn">返回列名</param>
		/// <param name="TableName">查询表名，可以指定联合查询的SQL语句(例如: Comment LEFT JOIN Users ON Comment.UserName = Users.UserName)</param>
		/// <param name="Filter">查询条件(例如: Name = 'name' and id=1 )</param>
		/// <param name="SortColumn">排序字段名，只能指定一个字段</param>
		/// <param name="Sorts">排序方式（DESC,ASC）</param>
		/// <param name="ID">用于分页的、不重复的字段</param>
		/// <param name="Group">分组语句（例：group by name,sex）</param>
		/// <param name="Total">输出参数：查询总数</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		IEnumerable<T> GetListPagedByStat(int startRowIndexId, int maxNumberRows, string StrColumn, string TableName, string Filter, string SortColumn, string Sorts, string ID, string Group, out int Total, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);
		/// <summary>
		/// 通过存储过程“Statistics_GetListByPage”，得到分页后的数据
		/// </summary>
		/// <typeparam name="TResult">实体类</typeparam>
		/// <param name="startRowIndexId">开始行索引</param>
		/// <param name="maxNumberRows">每页最大显示数量</param>
		/// <param name="StrColumn">返回列名</param>
		/// <param name="TableName">查询表名，可以指定联合查询的SQL语句(例如: Comment LEFT JOIN Users ON Comment.UserName = Users.UserName)</param>
		/// <param name="Filter">查询条件(例如: Name = 'name' and id=1 )</param>
		/// <param name="SortColumn">排序字段名，只能指定一个字段</param>
		/// <param name="Sorts">排序方式（DESC,ASC）</param>
		/// <param name="ID">用于分页的、不重复的字段</param>
		/// <param name="Group">分组语句（例：group by name,sex）</param>
		/// <param name="Total">输出参数：查询总数</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		IEnumerable<TResult> GetListPagedByStat<TResult>(int startRowIndexId, int maxNumberRows, string StrColumn, string TableName, string Filter, string SortColumn, string Sorts, string ID, string Group, out int Total, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);

		#endregion

		#region 执行SQL，检验是否存在数据
		/// <summary>
		/// 执行SQL，检验是否存在数据
		/// </summary>
		/// <param name="tableName"></param>
		/// <param name="strWhere"></param>
		/// <param name="param"></param>
		/// <param name="commandType"></param>
		/// <returns></returns>
		bool IsExistBySql(string tableName,string strWhere, object param = null, CommandType commandType = CommandType.Text);
		/// <summary>
		/// 执行SQL，检验是否存在数据
		/// </summary>
		/// <param name="tableName"></param>
		/// <param name="strWhere"></param>
		/// <param name="param"></param>
		/// <param name="commandType"></param>
		/// <returns></returns>
		Task<bool> IsExistBySqlAsync(string tableName, string strWhere, object param = null, CommandType commandType = CommandType.Text);
		#endregion

		#region 运行SQL语句,返回受影响的行数
		/// <summary>
		/// 执行SQL语句并返回受影响的行数
		/// </summary>
		/// <param name="sql">SQL语句，例：select id from Area where id in @ids</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="commandType">是存储过程还是SQL语句</param>
		/// <returns></returns>
		int ExeSQL(string sql, object param = null, CommandType commandType = CommandType.Text);
		/// <summary>
		/// 执行SQL语句并返回受影响的行数（异步）
		/// </summary>
		/// <param name="sql">SQL语句，例：select id from Area where id in @ids</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="commandType">是存储过程还是SQL语句</param>
		/// <returns></returns>
		Task<int> ExeSQLAsync(string sql, object param = null, CommandType commandType = CommandType.Text);
		#endregion

		#region 执行SQL，返回结果
		/// <summary>
		/// 执行SQL，返回结果。例：
		/// var s = testDal.GetBySQL《string》("select name from tablename where Id=@Id",new { Id = id });
		/// var s = testDal.GetBySQL《StoreM》("select * from tablename where Id=@Id",new { Id = id });
		/// var s = testDal.GetBySQL《dynamic》("select name,Code from tablename where Id=@Id",new { Id = id });
		/// </summary>
		/// <typeparam name="TResult"></typeparam>
		/// <param name="sql">SQL语句，例：select id from Area where id in @ids</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="commandType"></param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		TResult GetBySQL<TResult>(string sql, object param = null, CommandType commandType = CommandType.Text, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);
		/// <summary>
		/// 执行SQL，返回结果。例：
		/// var s = testDal.GetBySQL《string》("select name from tablename where Id=@Id",new { Id = id });
		/// var s = testDal.GetBySQL《StoreM》("select * from tablename where Id=@Id",new { Id = id });
		/// var s = testDal.GetBySQL《dynamic》("select name,Code from tablename where Id=@Id",new { Id = id });
		/// </summary>
		/// <typeparam name="TResult"></typeparam>
		/// <param name="sql">SQL语句，例：select id from Area where id in @ids</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="commandType"></param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		Task<TResult> GetBySQLAsync<TResult>(string sql, object param = null, CommandType commandType = CommandType.Text, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);
		#endregion

		#region 执行SQL，返回结果列表
		/// <summary>
		/// 执行SQL，返回结果。例：
		/// var s = testDal.GetBySQL《string》("select name from tablename where Id=@Id",new { Id = id });
		/// var s = testDal.GetBySQL《StoreM》("select * from tablename where Id=@Id",new { Id = id });
		/// var s = testDal.GetBySQL《dynamic》("select name,Code from tablename where Id=@Id",new { Id = id });
		/// </summary>
		/// <typeparam name="TResult"></typeparam>
		/// <param name="sql">SQL语句，例：select id from Area where id in @ids</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="commandType"></param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		IEnumerable<TResult> GetListBySQL<TResult>(string sql, object param = null, CommandType commandType = CommandType.Text, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);
		/// <summary>
		/// 执行SQL，返回结果。例：
		/// var s = testDal.GetBySQL《string》("select name from tablename where Id=@Id",new { Id = id });
		/// var s = testDal.GetBySQL《StoreM》("select * from tablename where Id=@Id",new { Id = id });
		/// var s = testDal.GetBySQL《dynamic》("select name,Code from tablename where Id=@Id",new { Id = id });
		/// </summary>
		/// <typeparam name="TResult"></typeparam>
		/// <param name="sql">SQL语句，例：select id from Area where id in @ids</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="commandType"></param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		Task<IEnumerable<TResult>> GetListBySQLAsync<TResult>(string sql, object param = null, CommandType commandType = CommandType.Text, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);

		/// <summary>
		/// 执行SQL，返回结果列表。
		/// 使用2种输入类型执行多重映射查询。这将返回一个单一类型，通过映射从原始类型组合而成。
		/// </summary>
		/// <typeparam name="TFirst">记录集中的第一个类型</typeparam>
		/// <typeparam name="TSecond">记录集中的第二个类型</typeparam>
		/// <typeparam name="TResult">要返回的组合类型</typeparam>
		/// <param name="sql">SQL语句</param>
		/// <param name="map">将行类型映射到返回类型的函数</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }）</param>
		/// <param name="splitOn">我们应该拆分并从中读取第二个对象的字段（默认值：“Id”）。</param>
		/// <param name="commandType">是存储过程还是SQL语句</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		IEnumerable<TResult> GetListBySQL<TFirst, TSecond, TResult>(string sql, Func<TFirst, TSecond, TResult> map, object param = null, string splitOn = "Id", CommandType commandType = CommandType.Text, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);
		/// <summary>
		/// 执行SQL，返回结果列表。
		/// 使用2种输入类型执行多重映射查询。这将返回一个单一类型，通过映射从原始类型组合而成。
		/// </summary>
		/// <typeparam name="TFirst">记录集中的第一个类型</typeparam>
		/// <typeparam name="TSecond">记录集中的第二个类型</typeparam>
		/// <typeparam name="TResult">要返回的组合类型</typeparam>
		/// <param name="sql">SQL语句</param>
		/// <param name="map">将行类型映射到返回类型的函数</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }）</param>
		/// <param name="splitOn">我们应该拆分并从中读取第二个对象的字段（默认值：“Id”）。</param>
		/// <param name="commandType">是存储过程还是SQL语句</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		Task<IEnumerable<TResult>> GetListBySQLAsync<TFirst, TSecond, TResult>(string sql, Func<TFirst, TSecond, TResult> map, object param = null, string splitOn = "Id", CommandType commandType = CommandType.Text, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);
		#endregion

		#region 执行SQL，返回DataTable
		/// <summary>
		/// 执行SQL，返回DataTable
		/// </summary>
		/// <param name="sql">SQL语句，例：select id from Area where id in @ids</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="commandType"></param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		DataTable GetDataTableBySql(string sql, object param = null, CommandType commandType = CommandType.Text, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);
		/// <summary>
		/// 执行SQL，返回DataTable
		/// </summary>
		/// <param name="sql">SQL语句，例：select id from Area where id in @ids</param>
		/// <param name="param">用于此查询的参数（例：new { Id = id }，如果是IN操作，传入：new { ids = new int[2] { 1, 2 } }）</param>
		/// <param name="commandType"></param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		Task<DataTable> GetDataTableBySqlAsync(string sql, object param = null, CommandType commandType = CommandType.Text, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None);
		#endregion
	}
}
